﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Activities;
using Xrm.Solutions.FrameworkSample.Workflow;
using System.Collections.Generic;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Fakes;
using Microsoft.Xrm.Sdk.Query;
using Xrm.Solutions.FrameworkSample.Common.Entities;
using Microsoft.Xrm.Sdk.Workflow.Fakes;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Messages.Fakes;
using Microsoft.QualityTools.Testing.Fakes;

namespace Xrm.Solutions.FrameworkSample.UnitTests
{
    [TestClass]
    public class TestTotalOpportunities
    {
        [TestMethod]
        public void TestCalculateTotal()
        {
            Guid accountId = Guid.NewGuid();

            TotalOpportunities activity = new TotalOpportunities();

            EntityReference accountRef = new EntityReference("account", accountId);
            IDictionary<string, object> inputs = new Dictionary<string, object>();
            inputs["AccountReference"] = accountRef;
            
            //Setup Runtime
            WorkflowInvoker invoker = new WorkflowInvoker(activity);

            StubIOrganizationService serviceStub = new StubIOrganizationService();
            serviceStub.ExecuteOrganizationRequest = (request) =>
                {
                    if (request is RetrieveMultipleRequest)
                    {
                        EntityCollection opps = new EntityCollection();
                        opps.Entities.Add(new Opportunity() { ActualValue = new Money(100) });
                        opps.Entities.Add(new Opportunity() { ActualValue = new Money(200) });
                        opps.Entities.Add(new Opportunity() { ActualValue = new Money(300) });
                        
                        ShimRetrieveMultipleResponse res = new Microsoft.Xrm.Sdk.Messages.Fakes.ShimRetrieveMultipleResponse()
                        {
                            EntityCollectionGet = () => {return opps;}                   
                        };

                        return res;
                    }
                    throw new NotImplementedException();
                };

            //IOrganizationServiceFactory Stub

            StubIOrganizationServiceFactory factoryStub = new StubIOrganizationServiceFactory();
            factoryStub.CreateOrganizationServiceNullableOfGuid = (id) =>
            {
                return serviceStub;
            };

            StubITracingService tracingStub = new StubITracingService();

            StubIWorkflowContext workflowStub = new StubIWorkflowContext();

            invoker.Extensions.Add(tracingStub);
            invoker.Extensions.Add(workflowStub);
            invoker.Extensions.Add(factoryStub);

            IDictionary<string, object> outputs;

            using (ShimsContext.Create())
            {
                outputs = invoker.Invoke(inputs);
            }

            Money actualTotal = outputs["Total"] as Money;
            decimal expectedTotal = 600;

            Assert.IsNotNull(actualTotal);
            Assert.AreEqual(expectedTotal, actualTotal.Value);
        }
    }
}
